#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QProcess>
char AT_CRLF[2] = {0x0D, 0x0A};

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow) {
  ui->setupUi(this);
  QString versionInfo =
      QString("%2 %1 by smaller").arg(version).arg("调试/解析工具");
  setWindowTitle(versionInfo);
  /* 设置icon */
  setWindowIcon(QIcon(":/img/log_64.ico"));
  currentUartCfg.baudRate = QSerialPort::Baud115200;
  currentUartCfg.dataBits = QSerialPort::Data8;
  currentUartCfg.paritys = QSerialPort::NoParity;
  currentUartCfg.stopBits = QSerialPort::OneStop;
  currentUartCfg.flowCtrl = QSerialPort::NoFlowControl;
  ui->comText->setText("comx,115200,8,None,1,None");

  comW = new uartCfg();

  comW->setCfgPtr(currentUartCfg);
  uartIsOpen = false;
  connect(comW, &uartCfg::setUartFinish, this, &MainWindow::setCurrentUartCfg);

  /* 开串口线程 */
  comThread = new uartWork(currentUartCfg);
  connect(comThread, &uartWork::readyread, this, &MainWindow::readFromCom,
          Qt::QueuedConnection);

  connect(comThread, &uartWork::openError, this, &MainWindow::openSucess,
          Qt::QueuedConnection);
  connect(comThread, &uartWork::errOccurred, this, &MainWindow::errorOccurred,
          Qt::QueuedConnection);
  connect(this, &MainWindow::sendData2Uart, comThread, &uartWork::writeData,
          Qt::QueuedConnection);
  connect(this, &MainWindow::upCfg2Uart, comThread, &uartWork::updateComCfg,
          Qt::QueuedConnection);
  connect(this, &MainWindow::startWork, comThread, &uartWork::updateComCfg,
          Qt::QueuedConnection);
  connect(this, &MainWindow::closeUart, comThread, &uartWork::stopThread,
          Qt::QueuedConnection);

  /* 默认显示 */
  ui->stopDis->setText("暂停显示");
  disPlayerFlag = true;
  ui->disPlayText->document()->setMaximumBlockCount(200);

  /* 默认选中显示文本 */
  ui->disModelBox->setCurrentIndex(ui->disModelBox->findText("文本显示"));

  /* 默认保存到我的文档目录 */
  QString configPath =
      QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) +
      "/mycoms/";
  QString logFilePath = configPath + "log/";

  /* 检测目录是否存在 不存在创建 */
  QFileInfo info(logFilePath);
  if (info.isDir() == false) {
    QDir dir;
    dir.mkpath(logFilePath);
  }

  logFilePath +=
      QDateTime::currentDateTime().toString("log-yyyy_MM_dd-hh_mm_ss") + ".log";
  /* 原始日志 */
  logPath = logFilePath;

  /* 初始化发送窗口 */
  senBtnList << ui->sendBtn01 << ui->sendBtn02 << ui->sendBtn03 << ui->sendBtn04
             << ui->sendBtn05 << ui->sendBtn06;

  sendHexList << ui->Hex01 << ui->Hex02 << ui->Hex03 << ui->Hex04 << ui->Hex05
              << ui->Hex06;

  sendLineList << ui->sendText01 << ui->sendText02 << ui->sendText03
               << ui->sendText04 << ui->sendText05 << ui->sendText06;

  for (int i = 0; i < senBtnList.count(); i++) {
    connect(senBtnList.at(i), &QPushButton::clicked, this,
            &MainWindow::sendText2Uart);
  }

  softInfoW = new aboutSoftInfo();
  authorW = new AuthorDialog;
}

MainWindow::~MainWindow() {

  delete authorW;
  delete softInfoW;
  delete comThread;
  delete comW;
  delete ui;
}

void MainWindow::readFromCom(QByteArray disData) {
  if (disData.isEmpty())
    return;
  QString disText, writeText, tmpText, logText, timeStr;
  uartSrcData = disData;

  do {
    if (disPlayerFlag == false)
      break;
    emit uartDataProc(uartSrcData);
    /* 判断显示 hex */
    writeText = pubFun.hex2QString(disData);
    if (0 == ui->disModelBox->currentIndex()) {
      /* 文本 */
      tmpText = QString(disData);
    } else {
      tmpText = writeText;
    }
    /* 写入文件 */
    {
      timeStr =
          QDateTime::currentDateTime().toString("[yyyy.MM.dd hh:mm:ss:zzz");
      writeText =
          timeStr +
          QString("接收[%1]]:").arg(QString::number(writeText.length())) +
          writeText + "\n";

      pubFun.writeFile(logPath, writeText + tmpText + "\n");
      logText = tmpText;
      if (ui->disTime->isChecked()) {
        logText =
            "\n" + timeStr +
            QString(" 接收[%1]]:").arg(QString::number(tmpText.length())) +
            tmpText;
      }
      if (ui->saveFile->isChecked() && true != savePath.isEmpty()) {
        pubFun.writeFile(savePath, logText);
      }
    }
    /* 显示 */
    if (ui->disTime->isChecked()) {
      disText =
          QDateTime::currentDateTime().toString("[yyyy.MM.dd hh:mm:ss:zzz") +
          QString(" 接收[%1]]:").arg(QString::number(tmpText.length())) +
          tmpText;
    } else {
      disText = tmpText;
    }
    ui->disPlayText->append(disText);
    ui->disPlayText->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
    uartSrcData.clear();

  } while (0);
}

void MainWindow::setCurrentUartCfg(comcfg_t cfg) { /* 更新串口配置 */
  QString comInfo, dataBits;
  currentUartCfg.portNum = cfg.portNum;
  currentUartCfg.baudRate = cfg.baudRate;
  currentUartCfg.dataBits = cfg.dataBits;
  currentUartCfg.paritys = cfg.paritys;
  currentUartCfg.stopBits = cfg.stopBits;
  currentUartCfg.flowCtrl = cfg.flowCtrl;

  emit upCfg2Uart(cfg);
  openSucess(true);
  comInfo += QString("com%1,").arg(QString::number(cfg.portNum));
  comInfo += (QString::number(cfg.baudRate) + QString(","));
  { /* dataBits */
    dataBits.clear();
    if (cfg.dataBits == QSerialPort::Data5) {
      dataBits = QString("5");
    } else if (cfg.dataBits == QSerialPort::Data6) {
      dataBits = QString("6");
    } else if (cfg.dataBits == QSerialPort::Data7) {
      dataBits = QString("7");
    } else if (cfg.dataBits == QSerialPort::Data8) {
      dataBits = QString("8");
    }
    comInfo += (dataBits + QString(","));
  }
  { /* 校验 */
    dataBits.clear();
    if (cfg.paritys == QSerialPort::NoParity) {
      dataBits = QString("None");
    } else if (cfg.paritys == QSerialPort::EvenParity) {
      dataBits = QString("奇校验");
    } else if (cfg.paritys == QSerialPort::OddParity) {
      dataBits = QString("偶校验");
    } else if (cfg.paritys == QSerialPort::MarkParity) {
      dataBits = QString("1");
    } else if (cfg.paritys == QSerialPort::SpaceParity) {
      dataBits = QString("0");
    }
    comInfo += (dataBits + QString(","));
  }

  { /* 停止位 */
    dataBits.clear();
    if (cfg.stopBits == QSerialPort::OneStop) {
      dataBits = QString("1");
    } else if (cfg.stopBits == QSerialPort::OneAndHalfStop) {
      dataBits = QString("1.5");
    } else if (cfg.stopBits == QSerialPort::TwoStop) {
      dataBits = QString("2");
    }
    comInfo += (dataBits + QString(","));
  }
  { /* 流控 */
    dataBits.clear();
    if (cfg.flowCtrl == QSerialPort::NoFlowControl) {
      dataBits = QString("None");
    } else if (cfg.flowCtrl == QSerialPort::SoftwareControl) {
      dataBits = QString("软控");
    } else if (cfg.flowCtrl == QSerialPort::HardwareControl) {
      dataBits = QString("硬控");
    } else if (cfg.flowCtrl == QSerialPort::UnknownFlowControl) {
      dataBits = QString("未知");
    }
    comInfo += dataBits;
  }
  ui->comText->setText(comInfo);
}

#if 0
void MainWindow::on_g11612MacBtn_clicked() {}

void MainWindow::on_gw11612SoftBtn_clicked() {}

#endif
void MainWindow::on_openComs_clicked() {
  if (uartIsOpen) {
    ui->openComs->setText("打开");
    emit closeUart();
    uartIsOpen = false;
  } else {
    ui->openComs->setText("关闭");
    emit upCfg2Uart(currentUartCfg);
    uartIsOpen = true;
  }
}

void MainWindow::errorOccurred(QString error) {
  if (false == error.isEmpty()) {
    QMessageBox::information(this, "串口错误", error);
  }
}

void MainWindow::openSucess(bool sucess) {
  if (sucess == true) {
    ui->openComs->setText("关闭");
    uartIsOpen = true;
  } else {
    ui->openComs->setText("打开");
    uartIsOpen = false;
  }
}

void MainWindow::on_stopDis_clicked() {
  (disPlayerFlag == true) ? (ui->stopDis->setText("继续显示"))
                          : (ui->stopDis->setText("暂停显示"));
  (disPlayerFlag == true) ? (disPlayerFlag = false) : (disPlayerFlag = true);
}

void MainWindow::on_disClear_clicked() { ui->disPlayText->clear(); }

void MainWindow::on_saveFile_clicked() {
  if (ui->saveFile->isChecked() == true) {
    /* 打开保存界面 */
    /* 用户选择需保存的路径 */
    QString sPath = QFileDialog::getSaveFileName(
        this, QString("保存日志文件"),
        QStandardPaths::writableLocation(QStandardPaths::DesktopLocation),
        tr("Text(*.txt)"));
    if (sPath.isEmpty() == true) {
      ui->saveFile->setChecked(false);
      savePath.clear();
      return;
    }
    savePath = sPath;
    ui->saveFile->setToolTip(savePath);
    ui->saveFile->setToolTipDuration(2000);
  } else {
    ui->saveFile->setToolTip("");
    savePath.clear();
  }
}

void MainWindow::sendText2Uart() {
  int count = 0, flag = 0;
  QByteArray sData;
  int sendLen = 0;
  QString tmpText, timeStr;
  QString sendTxt;
  QPushButton *sendBtn = qobject_cast<QPushButton *>(sender());
  if (senBtnList.count() == 0)
    return;
  if (sendHexList.count() == 0)
    return;
  for (count = 0; count < senBtnList.count(); count++) {
    if (senBtnList.at(count)->objectName() == sendBtn->objectName()) {
      flag = count;
      break;
    }
  }

  sendTxt = sendLineList.at(flag)->text();

  if (sendTxt.isEmpty())
    return;

  if (sendHexList.at(flag)->isChecked()) {
    /* 转hex */
    sendTxt = sendTxt.simplified().remove(QRegExp("\\s"));
    if (sendTxt.isEmpty())
      return;

    sData = pubFun.QString2Hex(sendTxt);
    if (ui->addTabEnter->isChecked()) {
      sData += QByteArray::fromRawData(AT_CRLF, getarraylen(AT_CRLF));
    }
    tmpText = pubFun.hex2QString(sData);

  } else {
    /* 不转换 */
    sData = sendTxt.toUtf8();
    if (ui->addTabEnter->isChecked()) {
      sData += QByteArray::fromRawData(AT_CRLF, getarraylen(AT_CRLF));
    }
    tmpText = sendTxt;
  }
  sendLen = sData.length();
  if (sendLen > 0) {
    timeStr = QDateTime::currentDateTime().toString("[yyyy.MM.dd hh:mm:ss:zzz");
    emit sendData2Uart(sData);
  }

  sendTxt = tmpText;

  tmpText = "\n" + timeStr +
            QString(" 发送[%1]]:").arg(QString::number(sendLen)) + sendTxt;
  if (ui->disTime->isChecked()) {
    sendTxt = tmpText;
  }

  smallerShare::writeFile(logPath, sendTxt);
  if (ui->saveFile->isChecked() && true != savePath.isEmpty()) {
    pubFun.writeFile(savePath, sendTxt);
  }

  ui->disPlayText->append(sendTxt);
  ui->disPlayText->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
}

void MainWindow::on_actionExit_triggered() {
  QMessageBox msgBox;
  msgBox.setWindowTitle(QString("警告!"));
  msgBox.setInformativeText("是否退出当前软件!");
  msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
  msgBox.setButtonText(QMessageBox::Ok, QString("确认"));
  msgBox.setButtonText(QMessageBox::Cancel, QString("取消"));
  msgBox.setDefaultButton(QMessageBox::Cancel);
  msgBox.setIcon(QMessageBox::Warning);
  if (QMessageBox::Ok == msgBox.exec()) {
    qApp->quit();
  }
}

void MainWindow::on_actionCfgUart_triggered() {
  if (false == comW->isHidden()) {
    comW->hide();
  }
  comW->show();
}

void MainWindow::on_actionSaveLog_triggered() {
  /* 打开保存界面 */
  /* 用户选择需保存的路径 */
  QString sPath = QFileDialog::getSaveFileName(
      this, QString("保存日志文件"),
      QStandardPaths::writableLocation(QStandardPaths::DesktopLocation),
      tr("Text(*.txt)"));
  if (sPath.isEmpty() == true) {
    ui->saveFile->setChecked(false);
    savePath.clear();
    return;
  }

  savePath = sPath;
  ui->saveFile->setToolTip(savePath);
  ui->saveFile->setToolTipDuration(2000);
  ui->saveFile->setChecked(true);
}

void MainWindow::on_actionDisClear_triggered() { ui->disPlayText->clear(); }

void MainWindow::on_actionDisStop_triggered() {
  (disPlayerFlag == true) ? (ui->stopDis->setText("继续显示"))
                          : (ui->stopDis->setText("暂停显示"));
  (disPlayerFlag == true) ? (ui->actionDisStop->setText("继续显示"))
                          : (ui->actionDisStop->setText("暂停显示"));
  (disPlayerFlag == true) ? (disPlayerFlag = false) : (disPlayerFlag = true);
}

void MainWindow::on_actionDixText_triggered() {
  ui->disModelBox->setCurrentIndex(ui->disModelBox->findText("文本显示"));
}

void MainWindow::on_actionDisHex_triggered() {
  ui->disModelBox->setCurrentIndex(ui->disModelBox->findText("hex显示"));
}

void MainWindow::on_actionaAoutSoft_triggered() {
  if (false == softInfoW->isHidden()) {
    softInfoW->hide();
  }
  softInfoW->show();
}

void MainWindow::on_actionAboutAuthor_triggered() {
  if (false == authorW->isHidden()) {
    authorW->hide();
  }
  authorW->show();
}

void MainWindow::on_actionExLog_triggered() {
  QFileInfo file(logPath);
  QStringList arg;
#if 0
  /* win下 */
  arg << QDir::toNativeSeparators(file.absoluteDir().path());
  QProcess::startDetached("explorer.exe", arg);
#endif
  #ifdef Q_OS_LINUX /* 修复Linux下打开日志目录问题，需要安装nautilus工具才可以用 */
   arg <<"-w" << file.absoluteDir().path();
   QProcess::startDetached("nautilus", arg);
#else
  arg << QDir::toNativeSeparators(file.absoluteDir().path());
   QProcess::startDetached("explorer.exe", arg);
#endif
}
